import openhtf
import os
import logging
from openhtf.output.callbacks import mfg_inspector
from openhtf.output.proto import mfg_event_converter
from openhtf.output.proto import mfg_event_pb2
from openhtf.output.servers import pub_sub
from openhtf.output.servers import web_gui_server
from openhtf.util import conf
from openhtf.util import data
from openhtf.output.servers import station_server
from servers import web_gui_server


class MyHistoryItemHandler(station_server.HistoryItemHandler):
    def get(self, file_name):
        fn = os.path.join(self.history_path, file_name)
        if not os.path.isfile(fn):
            self.write('Not found')
            self.set_status(404)
            return

        with open(fn, mode='rb') as f:
            me = mfg_event_pb2.MfgEvent()
            me.ParseFromString(f.read())
            tr = mfg_event_converter.test_record_from_mfg_event(me)
            test_record_dict = data.convert_to_base_types(tr)
            test_state_dict = station_server._test_state_from_record(test_record_dict,
                                                      station_server.StationPubSub._last_execution_uid)
            self.set_status(200)
            self.write(test_state_dict)

class MyHistoryAttachmentsHandler(station_server.HistoryAttachmentsHandler):
    def get(self, file_name, attachment_name):
        fn = os.path.join(self.history_path, file_name)
        if not os.path.isfile(fn):
            self.write('Not found')
            self.set_status(404)
            return

        with open(fn, mode='rb') as f:
            me = mfg_event_pb2.MfgEvent()
            me.ParseFromString(f.read())
            # TODO: could use sha1 here to check?
            desired_real = [a for a in me.attachment if a.name == attachment_name]
            if len(desired_real) > 0:
                self.write(desired_real[0].value_binary)
                self.set_status(200)
            else:
                self.write('Attachment not found in test')
                self.set_status(404)
     



class MyStationServer(station_server.StationServer,web_gui_server.WebGuiServer):
    def __init__(
      self,
      history_path) -> None:
    # Disable tornado's logging.
        tornado_logger = logging.getLogger('tornado')
        tornado_logger.propagate = False
        if not tornado_logger.handlers:
          tornado_logger.addHandler(logging.NullHandler())

        # Bind port early so that the correct port number can be used in the routes.
        sockets, port = web_gui_server.bind_port(int(station_server.CONF.station_server_port))

        # Set up the station watcher.
        station_watcher = station_server.StationWatcher(station_server.StationPubSub.publish_update)
        station_watcher.start()

        # Set up the SockJS endpoints.
        dashboard_class = station_server.DashboardPubSub.for_port(port)
        dash_router = station_server.sockjs.tornado.SockJSRouter(dashboard_class, '/sub/dashboard')
        station_router = station_server.sockjs.tornado.SockJSRouter(station_server.StationPubSub, '/sub/station')
        routes = dash_router.urls + station_router.urls

        # Set up the other endpoints.
        routes.extend((
            (r'/tests/(?P<test_uid>[\w\d:]+)/phases', station_server.PhasesHandler),
            (r'/tests/(?P<test_uid>[\w\d:]+)/plugs/(?P<plug_name>.+)',
             station_server.PlugsHandler),
            (r'/tests/(?P<test_uid>[\w\d:]+)/phases/(?P<phase_descriptor_id>\d+)/'
             'attachments/(?P<attachment_name>.+)', station_server.AttachmentsHandler),
        ))

        # Optionally enable history from disk.
        if history_path is not None:
          routes.extend((
              (r'/history', station_server.HistoryListHandler, {
                  'history_path': history_path
              }),
              #替换历史记录处理器
              (r'/history/(?P<file_name>[^/]+)', MyHistoryItemHandler, {
                  'history_path': history_path
              }),
              (r'/history/(?P<file_name>[^/]+)/attachments/(?P<attachment_name>.+)',
               MyHistoryAttachmentsHandler, {
                   'history_path': history_path
               }),
          ))

        # super(web_gui_server, self).__init__(routes, port, sockets=sockets)
        # 显示调用
        web_gui_server.WebGuiServer.__init__(self,routes, port, sockets=sockets)
        self.station_multicast = station_server.StationMulticast(port)
